perm filename PROGRA[F76,JMC] blob sn#238729 filedate 1976-09-29 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00003 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	.ss Numerical computation
C00009 00003	.SEC                     SEQUENTIAL PROGRAMS
C00011 ENDMK
C⊗;
.ss Numerical computation


	Numerical calculation and symbolic calculation must often
be combined, so LISP provides for numerical computation also.

	In the first place, we need to include numbers as parts
of symbolic expressions.  LISP has both integer and floating point
numbers which are regarded as atoms.
These numbers may be included as atoms in writing S-expressions.
Thus we can have the lists
%5(1 3 5)%1, %5(3.5 6.1 -7.2E9)%1, and %5(PLUS X 1.3)%1; the first
is a list of integers, the second a list of floating point numbers,
and the third a symbolic list containing both numberical and
non-numerical atoms.  Integers are written without decimal points
which are used to signal floating point numbers.  As in Fortran,
the letter %5E%1 is used to signal the exponent of a floating point
number which is a signed integer.  The sizes of numbers admitted
depends on the implementation.  When a dotted pair, say %5(1 . 2)%1
is wanted, the spaces around the dot distinguish it from the
list %5(1.2)%1 whose sole element is the floating point number 1.2.

	In publication language we will use ordinary mathematical
notation for numerical functions.  For exponentiation we will use
the usual superscript notation %3x%6y%1 when typographically convenient and
the linear Algol notation %3x↑y%1 when it isn't.  Of course, numerical
and symbolic calculation must often be combined, so that the function
giving the length of a list can be written

	%3length u ← %4if n %3u %4then %50 %4else %51 %3+ length %4d %3u%1.

	The internal notation for numerical functions is that used
in the examples given: %5(PLUS X Y ... Z)%1 for %3x+y+...+z%1,
%5(TIMES X ... Z)%1 for %3xy...z%1, %5(MINUS X)%1 for %3-x%1,
%5(DIFFERENCE X Y)%1 for %3x-y%1, %5(QUOTIENT X Y)%1 for %3x/y%1,
and %5(POWER X Y)%1 for %3x%6y%1.

	Since numbers that form part of list structures must be
represented by pointers anyway, there is room for a flag distinguishing
floating point numbers and integers.  Therefore, the arithmetic
operations are programmed to treat types dynamically, i.e. a variable
may take an integer value at one step of computation and a real value
at another.  The subroutines realizing the arithmetic functions make
the appropriate tests and create results of appropriate types.
This is slow compared to direct use of the machine's arithmetic
instructions, so that LISP can be efficiently used only when
the numerical calculations are small or at least small compared
to the symbolic calculations in a problem.

	Besides functions of numbers we need predicates on numbers
and the usual =, <, >, ≤, and ≥ are used with the internal
names %5EQUAL, LESSP, GREATERP, LESSEQP%1, and GREATEREQP%1, respectively.
Not all are implemented in all LISP systems, but of course the
remaining ones can be defined.  Besides that, the predicate %3numberp%1
is used to distinguish numbers from other atoms.

	It is worth remarking that including type flags in numbers
would benefit many programming languages besides LISP and would
not cost much in either storage or hardware.

	As a first example of a combined numeric and symbolic
computation, here is an interpreter for expressions with sums and
products.  Assume that the values of variables are given in
an %3association list%1, having the form

(<variable1>.<value1>) ... (<variablen>.<valuen>)),

e.g. %5((X . 5) (Y . 9.3) (Z . 2.1))%1.

	The function is

	%3numval[e,a] ← %4if %3numberp e %4then %3e
%4else if at %3e %4then d %3assoc[e,a]
%4else if a %3e %4eq %5PLUS %4then %3evplus[%4d %3e,a]
%4else if a %3e %4eq %5TIMES %4then %3evtimes[%4d %3e,a]%1

where

	%3evplus[u,a] ← %4if n %3u %4 then %50 %4else %3numval[%4a %3u,a] +
evplus[%4d %3u,a]%1,

	%3evtimes[u,a] ← %4if n %3u %4 then %51 %4else %3numval[%4a %3u,a] +
evtimes[%4d %3u,a]%1,

and

	%3assoc[x,a] ← %4if n %3a %4 then %5NIL
%4else if aa %3a %4eq %3x %4then da %3a %4else %3assoc[x,%4d %3a]%1.
.SEC                     SEQUENTIAL PROGRAMS


	In the previous chapters, we have emphasized the
functional style of programming most characteristic of LISP.
LISP also admits the sequential style of programming
dominant in Fortran and Algol.  In this chapter, we will
discuss the sequential programming facilities of LISP, about
which there is nothing surprising to be said, and discuss
the relation between functional and sequential programming.

.ss Sequential programming in LISP.

	As in other sequential programming languages, the
main kinds of sequential statement are the assignment statement,
the %4go to%1, and the procedure declaration.  Assignment statements
and %4go to%1s can also be conditional.

	In the main, we will use the notation of Algol 60 for the
publication language softening := to ← and correcting one error
in that language.

	The assignment statement is written

	%3leftside ← rightside;%1

where %3leftside%1 is an expression which evaluates to a variable
or an array element designator.